import re
import os
import emoji
from urllib.parse import urlparse
import hashlib
import csv
from settings import *
from motor.motor_asyncio import AsyncIOMotorClient
from PoolSql import my_sqlpool

class Base_save:
    def __init__(self, ways, keyword):
        self.ways = ways
        self.keyword = keyword
        self.filter_rule = re.compile('[\/\\\:\*\?\"\<\>\|]')
        self.rubbish_flag = True
        if ways == 2:
            self.init_sql()
        elif ways == 0:
            self.init_csv()
        elif ways == 1:
            self.init_mongo()

    def init_mongo(self):
        client = AsyncIOMotorClient(host=Mongo['host'], port=Mongo['port'])
        db = client[self.keyword]
        self.mongo_connect = db[self.keyword]

    def init_sql(self):
        self.sql_connect = my_sqlpool().get_connect()
        self.cursor = self.sql_connect.cursor()
        self.cursor.execute(
            f'CREATE TABLE IF NOT EXISTS {self.keyword} (title varchar(255) NOT NULL, author char(255), pushtime char(255), content longtext, url varchar(255), images longtext, title_md5 char(255), UNIQUE KEY title_md5 (title_md5))'
        )
        self.sql_connect.commit()

    def init_csv(self):
        file = open(os.path.join(Csv_Store + self.keyword + '.csv'), 'a+', encoding='utf_8_sig')
        fieldnames = ["title", "publish_time", "author", "content", "images"]
        self.writer = csv.DictWriter(file, fieldnames=fieldnames)
        self.writer.writeheader()

    def handling(self, data, url):
        title = data.get('title', '无标题')
        self.title = self.filter_title(title)
        self.author = data.get('author', '无作者')
        self.push_time = data.get('publish_time', '无推送时间')
        content = data.get('content', '无内容')
        self.content = self.filter_content(content)
        image_list = data.get('images', ['无'])
        image_list = self.filter_image(image_list, url)
        self.image_url = '\n'.join(image_list)
        self.title_md5 = hashlib.md5(self.title.encode('utf-8')).hexdigest()

    def filter_content(self, content):
        if (self.keyword in content) or self.rubbish_flag:
            if len(content) < 100:
                raise Exception('content too short')
            else:
                # 过滤长串空白字符
                content = re.sub('\s{5,10}', '', content)
                # 过滤特殊符号
                content = re.sub(self.filter_rule, '', content)
                # 过滤emoji表情
                content = emoji.demojize(content)
                return content
        else:
            raise Exception(f'rubbish item')

    def filter_title(self, title):
        if self.keyword in title:
            self.rubbish_flag = True
            if len(title) < 5:
                raise Exception('title too short')
            else:
                return title
        else:
            self.rubbish_flag = False

    def filter_image(self, image, url):
        images = list()
        for image in image:
            ParseResult = urlparse(image)
            if not hasattr(ParseResult, 'scheme'):
                image = 'https:' + image
                images.append(image)
            if not hasattr(ParseResult, 'netloc'):
                image = 'https://' + urlparse(url).netloc + image
                images.append(image)
            else:
                images.append(image)
        return images

    def save_to_mysql(self, data, url):
        cursor = self.sql_connect.cursor()
        insert_sql = f'insert into {self.keyword} (title, author, pushtime, content, url, images, title_md5) values("{self.title}", "{self.author}", "{self.push_time}", "{self.content}", "{url}", "{self.image_url}", "{self.title_md5}")'
        cursor.execute(insert_sql)
        self.sql_connect.commit()

    def save_to_csv(self, data, url):
        item = {
            'title': self.title,
            'author': self.author,
            'publish_time': self.push_time,
            'content': self.content,
            'images': self.image_url,
        }
        self.writer.writerow(item)

    def save_to_mongo(self, data, url):
        self.mongo_connect.insert_one({
            'title': self.title,
            'author': self.author,
            'push_time': self.push_time,
            'content': self.content,
            'image': self.image_url,
        })

    def execute(self, data, url):
        self.handling(data, url)
        if self.ways == 0:
            self.save_to_csv(data, url)
            return True
        elif self.ways == 1:
            self.save_to_mongo(data, url)
            return True
        elif self.ways == 2:
            self.save_to_mysql(data, url)
            return True
        else:
            raise Exception('without ways')

